<template>
  <a-row type="flex" :gutter="20">
    <!-- 数据列表 -->
    <a-col :xl="4" :lg="24" :md="24" style="margin-bottom: 10px" class="custom-border">
      <a-input v-model:value="deptName" placeholder="请输入合同名称" allow-clear size="small" style="margin-bottom: 20px" maxlength="40">
        <template #prefix>
          <search-outlined />
        </template>
      </a-input>
      <div class="body-container">
        <div v-for="(item, index) in filteredList" :key="item.id">
          <a-card
            style="margin-bottom: 5px"
            :body-style="{ padding: '0px' }"
            :class="['card-item', { 'selected-card': selectedCardIndex === index }]"
            @click.native="handleContractData(item, index)"
          >
            <div style="padding: 14px; font-size: 14px">
              <div>
                <span @click.stop="downloadFile(item.fileUrl)" style="color: blue; margin-right: 10px; cursor: pointer">{{ item.fileName }}</span>
              </div>
              <span>编号：{{ item.contractTypeCode }}</span>
              <span>
                结果：
                {{ item.responseCode == 200 ? '成功' : item.responseCode == 500 ? '失败' : '执行中' }}
              </span>
              <div class="bottom clearfix">
                <time class="time">{{ item.createTime }}</time>
                <a-button type="text" @click.stop="handleDelete(item)" style="color: blue">删除</a-button>
              </div>
            </div>
          </a-card>
        </div>
      </div>
    </a-col>

    <!-- 附件预览 -->
    <a-col :xl="14" :lg="24" :md="24" style="margin-bottom: 10px" v-if="!isUpload" class="custom-border">
      <a-row :gutter="10" class="mb8">
        <a-col :span="1.5">
          <a-button type="primary" ghost @click="handleAdd" size="small"> 返回合同提取 </a-button>
        </a-col>
      </a-row>
      <a-card>
        <div v-if="isPdf">
          <!-- 渲染 PDF 的容器 -->
          <object :data="nowFileUrl" type="application/pdf" width="100%" class="content"> PDF 预览失败 </object>
        </div>
        <div v-else>
          <p>未找到 PDF 文件</p>
        </div>
      </a-card>
    </a-col>

    <!-- 上传操作按钮 -->
    <a-col :xl="14" :lg="24" :md="24" style="margin-bottom: 10px" v-if="isUpload" class="custom-border">
      <a-form
        :model="formObj"
        ref="formRef"
        :rules="rules"
        @finish="onFinish"
        @finishFailed="onFinishFailed"
        :label-col="{ span: 8 }"
        :wrapper-col="{ span: 8 }"
        class="form-container"
      >
        <a-form-item label="大模型:" name="configId">
          <a-select v-model:value="formObj.configId" placeholder="请选择大模型">
            <a-select-option v-for="item in ModelSetList" :key="item.id" :value="item.id">{{ item.apiName }}</a-select-option>
          </a-select>
        </a-form-item>

        <a-form-item label="合同类型:" name="contractTypeCode">
          <a-select v-model:value="formObj.contractTypeCode" placeholder="请选择合同类型">
            <a-select-option v-for="item in CheckSetList" :key="item.id" :value="item.contractTypeCode">{{ item.contractTypeName }}</a-select-option>
          </a-select>
        </a-form-item>
        <a-upload-dragger
          v-model:fileList="nowfileList"
          ref="upload"
          name="file"
          :auto-upload="false"
          action=""
          drag
          @change="handleChange"
          :customRequest="httpRequest"
          :before-upload="beforeUpload"
          :max-count="1"
        >
          <p class="ant-upload-drag-icon">
            <InboxOutlined />
          </p>
          <p class="ant-upload-text">点击上传</p>
          <p class="ant-upload-hint">只能上传1个附件 且格式为{{ fileType }}</p>
        </a-upload-dragger>
        <a-form-item :wrapper-col="{ offset: 10, span: 16 }" style="margin-top: 20px">
          <a-button type="primary" @click="submitUpload" html-type="submit">开始附件校验</a-button>
        </a-form-item>
      </a-form>
    </a-col>

    <!-- 提取数据 -->
    <a-col :xl="6" :lg="24" :md="24" style="margin-bottom: 10px" class="custom-border">
      <a-table :data-source="alarmList" :loading="loading2" :pagination="false" :scroll="{ y: 500 }">
        <a-table-column title="提取字段" peop="column" align="center" />
        <a-table-column title="字段值" align="center" prop="value" :show-overflow-tooltip="true">
          <template #default="{ record }">
            {{ record.value || '--' }}
          </template>
        </a-table-column>
      </a-table>
    </a-col>
  </a-row>
</template>

<script setup>
  import { ref, reactive, computed, onMounted } from 'vue';
  import { message, Modal } from 'ant-design-vue';
  import { defHttp } from '/@/utils/http/axios';
  import { getToken } from '@/utils/auth';
  import { Api, getCheckSet, getModelConfig, getCheckRecord, getJsonData } from './contractExtract.api';
  import axios from 'axios';
  import { saveAs } from 'file-saver';
  import { Loading, useLoading } from '/@/components/Loading';
  // 数据定义
  const deptName = ref('');
  const isLoading = ref(true);
  const loadingMessage = ref('222222222222222222222222');
  const twoFileData = ref(null);
  const isUpload = ref(true);
  const upload = ref(null);
  const isPdf = ref(true);
  const nowFileUrl = ref('');
  const firstKey = ref('');
  const firstValue = ref('');
  const selectedCardIndex = ref(null);
  const nowfileList = ref([]);
  const fileType = ref(['pdf']);
  const formRef = ref(null);
  const ws = ref(null);
  const formObj = reactive({
    configId: undefined,
    contractTypeCode: undefined,
  });
  const rules = {
    configId: [{ required: true, message: '请选择大模型配置', trigger: 'change' }],
    contractTypeCode: [{ required: true, message: '请选择合同类型', trigger: 'change' }],
  };
  const ModelSetList = ref([]);
  const CheckSetList = ref([]);
  const alarmList = ref([]);
  const alarmRecord = ref([]);
  const loading2 = ref(false);
  const compState = reactive({
    absolute: false,
    loading: false,
    theme: 'dark',
    background: 'rgba(111,111,111,.7)',
    tip: '加载中...',
  });
  // 生命周期钩子
  onMounted(() => {
    getAlarmList();
    getContractType();
    getModelSetList();
  });
  // 计算属性
  const filteredList = computed(() => {
    return deptName.value ? alarmRecord.value.filter((item) => item.attachmentName.includes(deptName.value)) : alarmRecord.value;
  });
  const openLoading = (absolute) => {
    compState.absolute = absolute;
    compState.loading = true;
  };
  // 方法
  const handleMouseEnter = (item) => {
    // 处理鼠标移入
  };

  const handleMouseLeave = () => {
    // 处理鼠标移出
  };
  const handleChange = (file) => {
    nowfileList.value = file.fileList;
    // console.log('1111111111111111111', file, nowfileList.value);
  };
  const checkResult = (responseCheck) => {
    if (responseCheck === 'true') return '通过';
    if (responseCheck === 'false') return '未通过';
    return '校验失败';
  };
  const seePDF = (url, params, filename, config, isImage) => {
    const service = axios.create({
      // axios中请求配置有baseURL选项，表示请求URL公共部分
      baseURL: import.meta.env.VITE_GLOB_API_URL,
      // 超时
      timeout: 10000,
    });
    // request拦截器
    service.interceptors.request.use(
      (config) => {
        // 是否需要设置 token
        const isToken = (config.headers || {}).isToken === false;
        // 是否需要防止数据重复提交
        const isRepeatSubmit = (config.headers || {}).repeatSubmit === false;
        if (getToken() && !isToken) {
          config.headers['X-Access-Token'] = getToken(); // 让每个请求携带自定义token 请根据实际情况自行修改
        }
        // get请求映射params参数
        if (config.method === 'get' && config.params) {
          let url = config.url + '?' + tansParams(config.params);
          url = url.slice(0, -1);
          config.params = {};
          config.url = url;
        }
        if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) {
          const requestObj = {
            url: config.url,
            data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data,
            time: new Date().getTime(),
          };
          const requestSize = Object.keys(JSON.stringify(requestObj)).length; // 请求数据大小
          const limitSize = 5 * 1024 * 1024; // 限制存放数据5M
          if (requestSize >= limitSize) {
            console.warn(`[${config.url}]: ` + '请求数据大小超出允许的5M限制，无法进行防重复提交验证。');
            return config;
          }
          const sessionObj = cache.session.getJSON('sessionObj');
          if (sessionObj === undefined || sessionObj === null || sessionObj === '') {
            cache.session.setJSON('sessionObj', requestObj);
          } else {
            const s_url = sessionObj.url; // 请求地址
            const s_data = sessionObj.data; // 请求数据
            const s_time = sessionObj.time; // 请求时间
            const interval = 1000; // 间隔时间(ms)，小于此时间视为重复提交
            if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) {
              const message = '数据正在处理，请勿重复提交';
              console.warn(`[${s_url}]: ` + message);
              return Promise.reject(new Error(message));
            } else {
              cache.session.setJSON('sessionObj', requestObj);
            }
          }
        }
        return config;
      },
      (error) => {
        console.log(error);
        Promise.reject(error);
      }
    );

    // 响应拦截器
    service.interceptors.response.use(
      (res) => {
        // 未设置状态码则默认成功状态
        const code = res.data.code || 200;
        // 获取错误信息
        const msg = errorCode[code] || res.data.msg || errorCode['default'];
        // 二进制数据则直接返回
        if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') {
          return res.data;
        }
        if (code === 401) {
          if (!isRelogin.show) {
            isRelogin.show = true;
            MessageBox.confirm('登录状态已过期，您可以继续留在该页面，或者重新登录', '系统提示', {
              confirmButtonText: '重新登录',
              cancelButtonText: '取消',
              type: 'warning',
            })
              .then(() => {
                isRelogin.show = false;
                store.dispatch('LogOut').then(() => {
                  location.href = '/index';
                });
              })
              .catch(() => {
                isRelogin.show = false;
              });
          }
          return Promise.reject('无效的会话，或者会话已过期，请重新登录。');
        } else if (code === 500) {
          Message({ message: msg, type: 'error' });
          return Promise.reject(new Error(msg));
        } else if (code === 601) {
          Message({ message: msg, type: 'warning' });
          return Promise.reject('error');
        } else if (code !== 200) {
          Notification.error({ title: msg });
          return Promise.reject('error');
        } else {
          return res.data;
        }
      },
      (error) => {
        console.log('err' + error);
        let { message } = error;
        if (message == 'Network Error') {
          message = '后端接口连接异常';
        } else if (message.includes('timeout')) {
          message = '系统接口请求超时';
        } else if (message.includes('Request failed with status code')) {
          message = '系统接口' + message.substr(message.length - 3) + '异常';
        }
        Message({ message: message, type: 'error', duration: 5 * 1000 });
        return Promise.reject(error);
      }
    );
    // this.downloadLoadingInstance = Loading.service({
    //   text: '正在加载预览文件，请稍候',
    //   spinner: 'el-icon-loading',
    //   background: 'rgba(0, 0, 0, 0.7)',
    // });
    const keys = Object.keys(params);
    if (keys.length > 0) {
      firstKey.value = keys[0];
      firstValue.value = params[firstKey.value];
    } else {
      console.log('The object is empty.');
    }
    return service
      .get(url + `?${firstKey.value}=${firstValue.value}`, {
        headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
        responseType: 'blob',
        ...config,
      })
      .then(async (response) => {
        console.log('0000000000000000000', response);

        const blob = new Blob([response.data], { type: 'application/pdf' });
        const pdfURL = URL.createObjectURL(blob);
        nowFileUrl.value = pdfURL;
        console.log('111111111111111111', nowFileUrl.value);
        // this.downloadLoadingInstance.close();

        // this.downloadLoadingInstance.close();
      })
      .catch((r) => {
        // console.error(r);
        // Message.error("下载文件出现错误，请联系管理员！");
        // this.downloadLoadingInstance.close();
      });
  };
  const seePDF2 = (url, filename) => {
    // 发起请求（设置 responseType: 'blob'）
    const axurl = import.meta.env.VITE_GLOB_API_URL + url;
    axios
      .get(axurl, {
        headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'X-Access-Token': getToken() },
        params: { url: filename },
        responseType: 'blob',
      })
      .then((response) => {
        var blob = {};
        if (filename.includes('.pdf')) {
          blob = new Blob([response.data], { type: 'application/pdf' });
          nowFileUrl.value = URL.createObjectURL(blob);
          console.log('000000000000000000000', nowFileUrl.value);
        } else {
          blob = new Blob([response.data], { type: 'image/jpg' });
          nowFileUrl.value = URL.createObjectURL(blob);
          console.log('111111111111111111', nowFileUrl.value);
        }
        // 创建 Blob 对象
        // const blob = new Blob([response.data], { type: response.data.type });
        // // 创建临时链接并触发下载
        // const link = document.createElement('a');
        // link.href = window.URL.createObjectURL(blob);
      });
  };
  const downloadPDF = (url, params, filename) => {
    const keys = Object.keys(params);
    if (keys.length > 0) {
      firstKey.value = keys[0];
      firstValue.value = params[firstKey.value];
    } else {
      console.log('The object is empty.');
    }
    // let config = {
    //   headers: {
    //     'Content-Type': 'multipart/form-data',
    //   },
    // };
    const axurl = import.meta.env.VITE_GLOB_API_URL + url;
    // config.headers['Authorization'] = 'Bearer' + getToken();
    return axios
      .get(axurl + `?${firstKey.value}=${firstValue.value}`, {
        headers: { Authorization: getToken(), 'X-Access-Token': getToken() },
        responseType: 'blob',
      })
      .then(async (response) => {
        const blob = new Blob([response.data], { type: 'application/pdf' });
        saveAs(blob, filename);
      });
  };
  const handleContractData = (item, index) => {
    selectedCardIndex.value = index;
    isUpload.value = false;
    alarmList.value = [];
    isPdf.value = item.fileUrl.includes('.pdf');
    seePDF2('/v2/local/download', item.fileUrl);
    return axios
      .get(import.meta.env.VITE_GLOB_API_URL + '/pdfImg2Txt/getJsonData/' + `${item.id}`, {
        headers: { Authorization: getToken(), 'X-Access-Token': getToken() },
      })
      .then(async (response) => {
        console.log('0000000000000000000', response);
        alarmList.value = response.records;
      });
    // alarmList.value.push(item);
  };

  const downloadFile = (fileUrl) => {
    if (!fileUrl) {
      message.error('该记录无附件！');
      return;
    }
    downloadPDF('/v2/local/download', { url: fileUrl }, fileUrl?.split(/[\/\\]/).pop());
  };

  const getModelSetList = async () => {
    const result = await getModelConfig({ pageNum: 1, pageSize: 999 });
    // console.log('1111111111111111111', result.records);
    ModelSetList.value = result.records;
  };
  const getContractType = async () => {
    const result = await getCheckSet({ pageNum: 1, pageSize: 999 });
    // console.log('22222222222222222附件类型', result.records);
    CheckSetList.value = result.records;
  };

  const getAlarmList = async (isFirst) => {
    openLoading(true);
    const result = await getCheckRecord({ pageNum: 1, pageSize: 999 });
    // console.log('33333333333333333333333列表', result.records);
    // if (response.code === '200') {
    alarmRecord.value = result.records;
    if (isFirst === 1) {
      handleContractData(alarmRecord.value[0], 0);
    }
    // } else {
    //   message.error(response.msg);
    // }
  };

  const beforeUpload = (file) => {
    twoFileData.value = file; // 获取文件的二进制数据
    const fileName = file.name.split('.');
    const fileExt = fileName[fileName.length - 1];
    const isTypeOk = ['png', 'jpg', 'jpeg', 'pdf'].includes(fileExt);
    if (!isTypeOk) {
      message.error(`附件格式不正确, 请上传 png/jpg/jpeg/pdf 格式附件!`);
      return false;
    }
    if (!formObj.contractTypeCode) {
      message.warning('请先选择合同类型！');
      return false;
    }
    return false;
  };

  const handleRemove = () => {
    nowfileList.value = [];
  };

  const httpRequest = async (file) => {
    // const { file } = options;
    const fd = new FormData();
    fd.append('file', file);
    fd.append('contractTypeCode', formObj.contractTypeCode);
    fd.append('configId', formObj.configId);
    //TODO 请求怎样处理的问题
    let headers = {
      'Content-Type': 'multipart/form-data;boundary = ' + new Date().getTime(),
    };
    defHttp.post({ url: '/pdfImg2Txt/upload', params: fd, headers }, { isTransformResponse: false }).then((res) => {
      message.success('开始进行合同提取!');
      join();
      // getAlarmList(1);
    });
  };
  const join = () => {
    const wsuri = import.meta.env.VITE_GLOB_WS_URL + '/websocket/message';
    ws.value = new WebSocket(wsuri);
    const self = this;
    ws.value.onopen = function (event) {
      self.text_content = self.text_content + '已经打开连接!' + '\n';
    };
    ws.value.onmessage = function (event) {
      self.text_content = event.data + '\n';
      if (JSON.parse(event.data).responseCode == 500) {
        message.error('合同提取失败！');
        // self.$message.error('合同提取失败！');
        getAlarmList(1);
      } else if (JSON.parse(event.data).responseCode == 200) {
        getAlarmList(1);
        message.error('合同提取成功！');
        // self.$message.success('合同提取成功！');
      }
    };
    ws.value.onclose = function (event) {
      self.text_content = self.text_content + '已经关闭连接!' + '\n';
    };
  };
  const submitUpload = () => {
    formRef.value.validate().then(() => {
      if (nowfileList.value.length === 0) {
        message.error('请上传合同！');
      } else {
        isUpload.value = false;
        httpRequest(twoFileData.value);
      }
    });
  };

  const handleAdd = () => {
    formObj.configId = undefined;
    formObj.contractTypeCode = undefined;
    nowfileList.value = [];
    isUpload.value = true;
    alarmList.value = [];
    selectedCardIndex.value = null;
  };
</script>

<style scoped>
  .form-container {
    margin-top: 50px;
  }
  /* 样式保持不变 */
  .app-container {
    padding-bottom: 0;
  }
  .custom-border {
    border: 1px solid #dcdcdc; /* 你可以根据需要调整边框的宽度和颜色 */
    padding: 10px; /* 可选，为了视觉效果，你可以添加一些内边距 */
  }
  .block {
    white-space: nowrap;
    overflow-x: auto; /* 启用横向滚动 */
    max-width: 600px; /* 限制容器宽度 */
  }
  .custom-carousel .el-carousel__indicator {
    bottom: 10px; /* 调整指示器的位置 */
  }

  .custom-carousel .el-carousel__indicator span {
    background-color: rgba(255, 255, 255, 0.7); /* 设置指示器背景色 */
    width: 12px; /* 增加指示器大小 */
    height: 12px; /* 增加指示器大小 */
    border-radius: 50%; /* 使指示器变为圆形 */
    transition:
      background-color 0.3s ease,
      transform 0.3s ease; /* 增加过渡效果 */
  }

  .custom-carousel .el-carousel__indicator .is-active {
    background-color: #409eff; /* 设置激活状态下的指示器颜色 */
    transform: scale(1.2); /* 激活状态下指示器放大 */
  }
  .el-carousel__indicator {
    background-color: red;
  }
  /* 修改选中行的背景颜色 */
  .el-table .el-table__body .el-table__row.selected:hover {
    background-color: #f5f5f5 !important; /* 修改鼠标移入时的选中行背景颜色 */
  }

  /* 修改选中行的背景颜色（不加 hover） */
  .el-table .el-table__body .el-table__row.selected {
    background-color: #cbe7ff !important; /* 选中的行背景颜色 */
  }
  .body-container {
    height: 80vh;
    overflow: scroll;
  }
  ::v-deep .el-upload-dragger {
    width: 46vw !important;
  }
  .content {
    height: 78vh; /* 子组件高度为父容器的 50% */
  }
  .responsive-image {
    width: 100%; /* 图片宽度铺满容器 */
    height: auto; /* 高度自适应，保持比例 */
    display: block; /* 避免图片下方有空白间隙 */
  }
  .card-item {
    transition: all 0.3s ease;
  }

  .selected-card {
    border-color: #409eff; /* Element Plus 的主色 */
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
    transform: translateY(-5px);
  }
</style>
